package com.ddwl.order.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ddwl.common.constant.RabbitMqConstants;
import com.ddwl.order.annotation.Erp;
import com.ddwl.schema.bo.order.ThirdPartRecordBo;
import com.ddwl.schema.vo.base.RestVo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * @author Fu Zhaohui
 */
@Slf4j
@Aspect
@Component
public class ErpLogAop {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Pointcut("execution(* com.ddwl.order.controller.OrderOpenApiController.*(..))")
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object Around(ProceedingJoinPoint pjp) throws Throwable{
        Object r = pjp.proceed();
        MethodSignature sign = (MethodSignature) pjp.getSignature();
        Method method = sign.getMethod();
        //获取方法上的注解
        Erp erp = method.getAnnotation(Erp.class);
        if(erp==null){
            return r;
        }
        Object[]  ags =   pjp.getArgs();
        //请求方法
        String service=pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName() + "()";
        //请求参数
        String request = JSON.toJSONString(ags[0]);
        //返回结果
        String response =JSON.toJSONString(r);
        sentThirdPartMsg(service,request,response);
        log.info("args:  ---{}", ags);
        log.info(erp.name() + " 调用正常记录  ---");
        log.info("返回值:"+ JSON.toJSONString(r));
        return r;
    }

    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint,Throwable e) {
        try {
            MethodSignature sign = (MethodSignature) joinPoint.getSignature();
            Method method = sign.getMethod();
            //获取方法上的注解
            Erp erp = method.getAnnotation(Erp.class);
            if(erp==null){
                return;
            }

            Object[]  ags =   joinPoint.getArgs();
            //请求方法
            String service=joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()";
            //请求参数
            String request = JSON.toJSONString(ags[0]);
            //返回结果
            String response =JSONObject.toJSONString(RestVo.error(e.getMessage()));
            sentThirdPartMsg(service,request,response);
            log.info(erp.name() + " 调用异常记录  ---");
            log.info("入参  --- {}", ags);
            log.info("异常 e= " +e.getMessage());

        } catch (Exception ex) {
            log.error("\naspect error", ex);
        }
    }

    /**
     * 发送记录第三方调用信息消息(订单详情)
     * @param service
     * @param request
     * @param response
     */
    public void sentThirdPartMsg(String service,String request,String response){
        JSONObject req = JSON.parseObject(request);
        JSONObject res = JSON.parseObject(response);
        JSONObject param = req.getJSONObject("param");
        log.info("开始发送记录第三方调用信息消息 appId={},requestService={}", req.getString("app_id"),
                service);
        //发送记录第三方调用信息消息
        ThirdPartRecordBo partRecordBo=new ThirdPartRecordBo();
        if (param==null){
            partRecordBo.setAppId(req.getString("appId"));
            partRecordBo.setRequestTime(req.getTimestamp("timestamp").toInstant());
        }else {
            partRecordBo.setAppId(param.getString("appId"));
            partRecordBo.setRequestTime(param.getTimestamp("timestamp").toInstant());
        }
        partRecordBo.setRequestService(service);
        partRecordBo.setRequestConditions(request);
        partRecordBo.setRequestResult(res.getInteger("code"));
        partRecordBo.setRequestResultMsg(res.getString("msg"));
        String s = JSON.toJSONString(partRecordBo);
        rabbitTemplate.convertAndSend(RabbitMqConstants.THIRD_PART_RECORD_QUEUE,s);
    }

}